package com.vegetable.common.aspect;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.vegetable.modules.entity.inbound.AgentDelivery;
import com.vegetable.modules.entity.inbound.AgentDeliveryDetail;
import com.vegetable.modules.entity.stock.PriceAlert;
import com.vegetable.modules.mapper.inbound.AgentDeliveryDetailMapper;
import com.vegetable.modules.mapper.inbound.AgentDeliveryMapper;
import com.vegetable.modules.service.stock.IPriceAlertService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 价格预警切面
 * 在每次调用AgentDeliveryServiceImpl.saveOrEdit方法后检查价格预警
 *
 * @author qoder
 * @since 2025-09-11
 */
@Slf4j
@Aspect
@Component
public class PriceAlertAspect {

    private final IPriceAlertService priceAlertService;
    private final AgentDeliveryDetailMapper agentDeliveryDetailMapper;
    private final AgentDeliveryMapper agentDeliveryMapper;

    public PriceAlertAspect(IPriceAlertService priceAlertService, 
                           AgentDeliveryDetailMapper agentDeliveryDetailMapper,
                           AgentDeliveryMapper agentDeliveryMapper) {
        this.priceAlertService = priceAlertService;
        this.agentDeliveryDetailMapper = agentDeliveryDetailMapper;
        this.agentDeliveryMapper = agentDeliveryMapper;
    }

    /**
     * 在每次调用AgentDeliveryServiceImpl.saveOrEdit方法后执行价格预警检查
     */
    @After("execution(* com.vegetable.modules.service.inbound.impl.AgentDeliveryServiceImpl.saveOrEdit(..)) && args(agentDelivery,..)")
    public void checkPriceAlertAfterSave(JoinPoint joinPoint, AgentDelivery agentDelivery) {
        log.info("开始执行价格预警检查");
        
        try {
            // 获取订单中涉及的商品ID集合
            Set<Long> commodityIds = agentDelivery.getCommodities().stream()
                    .map(AgentDeliveryDetail::getCommodityId)
                    .collect(Collectors.toSet());
            
            if (commodityIds.isEmpty()) {
                log.info("订单中没有商品，无需检查价格预警");
                return;
            }
            
            // 获取所有启用的价格预警设置，且商品ID在订单商品ID集合中
            QueryWrapper<PriceAlert> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("is_enabled", 1);
            queryWrapper.in("commodity_id", commodityIds);
            List<PriceAlert> priceAlerts = priceAlertService.list(queryWrapper);
            
            if (priceAlerts.isEmpty()) {
                log.info("没有启用的价格预警设置");
                return;
            }
            
            // 检查每个商品的价格预警
            for (PriceAlert priceAlert : priceAlerts) {
                try {
                    checkPriceAlertForCommodity(priceAlert, agentDelivery.getOrderTime());
                } catch (Exception e) {
                    log.error("检查商品{}的价格预警时发生异常", priceAlert.getCommodityId(), e);
                }
            }
            
            log.info("价格预警检查执行完成");
        } catch (Exception e) {
            log.error("执行价格预警检查时发生异常", e);
        }
    }

    /**
     * 检查单个商品的价格预警
     */
    private void checkPriceAlertForCommodity(PriceAlert priceAlert, java.util.Date orderTime) {
        Long commodityId = priceAlert.getCommodityId();
        log.debug("检查商品{}的价格预警", commodityId);
        
        try {
            // 获取指定日期商品的最高价格和最低价格
            PriceRangeWithOrderIds priceRange = getPriceRangeWithOrderIds(commodityId, orderTime);
            if (priceRange == null || priceRange.getMaxPrice() == null || priceRange.getMinPrice() == null) {
                log.debug("商品{}在指定日期没有价格数据", commodityId);
                return;
            }
            
            // 计算价格差异金额
            BigDecimal priceDifference = calculatePriceDifference(priceRange.getMaxPrice(), priceRange.getMinPrice());
            
            // 检查是否超过阈值
            if (priceDifference.compareTo(priceAlert.getPriceThreshold()) >= 0) {
                // 不再创建价格预警记录，只记录日志
                log.info("商品{}触发价格预警，最高价格：{}元(订单ID:{})，最低价格：{}元(订单ID:{})，价格差异：{}元，阈值：{}元", 
                        commodityId, priceRange.getMaxPrice(), priceRange.getMaxPriceOrderId(), 
                        priceRange.getMinPrice(), priceRange.getMinPriceOrderId(),
                        priceDifference, priceAlert.getPriceThreshold());
            }
        } catch (Exception e) {
            log.error("检查商品{}的价格预警时发生异常", commodityId, e);
        }
    }

    /**
     * 获取指定日期商品的最高价格和最低价格及对应的订单ID
     */
    private PriceRangeWithOrderIds getPriceRangeWithOrderIds(Long commodityId, java.util.Date orderTime) {
        // 使用Mapper中的方法查询指定日期商品的最高价格和最低价格及订单ID
        java.util.Map<String, Object> result = agentDeliveryMapper.getPriceRangeByOrderTime(commodityId, orderTime);
        
        if (result != null && !result.isEmpty()) {
            Object maxPriceObj = result.get("maxPrice");
            Object minPriceObj = result.get("minPrice");
            Object maxPriceOrderIdObj = result.get("maxPriceOrderId");
            Object minPriceOrderIdObj = result.get("minPriceOrderId");
            
            if (maxPriceObj != null && minPriceObj != null) {
                BigDecimal maxPrice = new BigDecimal(maxPriceObj.toString());
                BigDecimal minPrice = new BigDecimal(minPriceObj.toString());
                Long maxPriceOrderId = maxPriceOrderIdObj != null ? Long.valueOf(maxPriceOrderIdObj.toString()) : null;
                Long minPriceOrderId = minPriceOrderIdObj != null ? Long.valueOf(minPriceOrderIdObj.toString()) : null;
                return new PriceRangeWithOrderIds(maxPrice, minPrice, maxPriceOrderId, minPriceOrderId);
            }
        }
        
        return null;
    }

    /**
     * 计算价格差异金额
     */
    private BigDecimal calculatePriceDifference(BigDecimal maxPrice, BigDecimal minPrice) {
        // 计算价格差异金额（最高价-最低价）
        BigDecimal difference = maxPrice.subtract(minPrice);
        return difference.abs().setScale(6, RoundingMode.HALF_UP);
    }
    
    /**
     * 价格范围类（包含订单ID信息）
     */
    private static class PriceRangeWithOrderIds {
        private BigDecimal maxPrice;
        private BigDecimal minPrice;
        private Long maxPriceOrderId;
        private Long minPriceOrderId;
        
        public PriceRangeWithOrderIds(BigDecimal maxPrice, BigDecimal minPrice, Long maxPriceOrderId, Long minPriceOrderId) {
            this.maxPrice = maxPrice;
            this.minPrice = minPrice;
            this.maxPriceOrderId = maxPriceOrderId;
            this.minPriceOrderId = minPriceOrderId;
        }
        
        public BigDecimal getMaxPrice() {
            return maxPrice;
        }
        
        public BigDecimal getMinPrice() {
            return minPrice;
        }
        
        public Long getMaxPriceOrderId() {
            return maxPriceOrderId;
        }
        
        public Long getMinPriceOrderId() {
            return minPriceOrderId;
        }
    }
}